home *** CD-ROM | disk | FTP | other *** search
- /* IFF ILBM routines */
- /* NOTE: This only works if you link with libnix. It fails with ixemul *
- because ixemul.library is opened by the maintask and iffpage is called *
- by the subtask. The problem are the file-commands which should be replaced *
- by Amigados-commands (Open(), Write()...) or you link with libnix */
-
- #include "PostPre.h"
- #include "Global.h"
-
- extern int page_counter;
- extern BPTR outfh;
-
- int iffseq = 0;
- static int newpage=TRUE, counter, end, ifferr, xa, ya, i,
- j, k, ch, fslen;
- static long addr1, addr2;
- static UWORD w;
- static char fname[110], fsnum[10];
- static FILE *ifffptr;
-
- /* Find the greatest common divisor of two positive integers. If one is
- * zero the result is the other */
-
- int igcd(int n, int m)
- { unsigned int n1, m1, r;
- if (n > m)
- { n1 = n;
- m1 = m;
- }
- else if (m > n)
- { n1 = m;
- m1 = n;
- }
- else
- return n;
- while (m1 != 0)
- { r = n1 % m1;
- n1 = m1;
- m1 = r;
- }
- return (int) n1;
- }
-
- /* Put a byte */
-
- static void iffputb(int b)
- { if (ifferr) return;
- if (putc((int) b, ifffptr) == EOF)
- { ifferr = 1;
- return;
- }
- }
-
- /* Put a word */
-
- static void iffputw(int w)
- { iffputb(w>>8);
- iffputb(w);
- }
-
- /* Put a long */
-
- static void iffputl(int l)
- { iffputb(l>>24);
- iffputb(l>>16);
- iffputb(l>>8);
- iffputb(l);
- }
-
- /* Put a string */
-
- static void iffputs(char *str)
- { while (*str) iffputb(*str++);
- }
-
- /* Pack a bitmap row */
-
- static void iffpack(char *buf, int len)
- { int b, c, l;
- if (ifferr) return;
- l = 0;
- while (len--)
- { b = *buf++; /* Pick up a byte */
- c = 1;
- while (len && *buf == b && c < 128)
- { c++;
- buf++;
- len--; /* See if it begins a run */
- }
- if (c == 2 && /* If a two byte run */
- l > 0 && /* and preceeded by literals */
- l <= 125 && /* and not more than 125 of them */
- (len <= 2 || /* and no more than 2 bytes left */
- *buf != *(buf + 1))) /* or not followed by a run */
- { c = 1; /* Then make it a literal */
- buf--;
- len++;
- }
- if (c == 1) /* If not a run */
- { l++; /* Then it must be a literal */
- c = 0;
- }
- if (l > 0 && /* If we have some literals */
- (c > 1 || /* and beginning a run */
- l == 127 || /* or reached 127 */
- len == 0)) /* or no more bytes left */
- { if (putc((unsigned char) (l - 1), ifffptr) == EOF)
- { ifferr = 1;
- return;
- }
- while (l) /* Then write out the literals */
- { if (putc((unsigned char) *(buf - c - l), ifffptr) == EOF)
- { ifferr = 1;
- return;
- }
- l--;
- }
- }
- if (c > 1) /* If we have a run, write it */
- { if (putc((unsigned char) (1-c), ifffptr) == EOF)
- { ifferr = 1;
- return;
- }
- if (putc((unsigned char) b, ifffptr) == EOF)
- { ifferr = 1;
- return;
- }
- }
- }
- }
-
- /* Determine the current address */
-
- static long ifftell(void)
- { long addr;
- if (ifferr) return 0;
- if ((addr = ftell(ifffptr)) == -1)
- { ifferr = 1;
- return 0;
- }
- return addr;
- }
-
- /* Fix up the length of a chunk */
-
- static void ifffixup(long addr)
- { long size;
- if (ifferr) return;
- if ((size = ftell(ifffptr)) == -1)
- { ifferr = 1;
- return;
- }
- if (size & 1) iffputb(0);
- size = size - addr - 8;
- if (fseek(ifffptr, addr + 4, 0) != 0)
- { ifferr = 1;
- return;
- }
- iffputl(size);
- if (fseek(ifffptr, 0, 2) != 0)
- { ifferr = 1;
- return;
- }
- }
-
- /* Write the page to the iff output file */
-
- void iffpage(struct BitMap *my_iff_bm)
- {
-
- /* Compute the aspect ratio. Make sure the values fit into a byte */
-
- xa = parm.page.yden;
- ya = parm.page.xden;
- i = igcd(xa, ya);
- xa /= i;
- ya /= i;
- while (xa > 255 && ya > 255)
- {
- xa /= 2;
- ya /= 2;
- }
-
- /* Construct the file name. Copy it, replacing "*" by the sequence
- * number. The scan it backwards replacing "?" by digits */
-
- if(newpage)
- {
- i = iffseq;
- iffseq++;
- fslen = 0;
- while (i)
- {
- fsnum[fslen++] = i % 10 + '0';
- i /= 10;
- }
- i = j = 0;
- for (;;)
- {
- if (j > 100)
- {
- ioerror = errioerror;
- return;
- }
- ch = Options.PostOpts.iffname[i++];
- if (ch == '*')
- {
- k = fslen;
- while (k--) fname[j++] = fsnum[k];
- }
- else fname[j++] = ch;
- if (ch == 0) break;
- }
- k = 0;
- while (--j)
- {
- if (fname[j] == '?') fname[j] = (k < fslen) ? fsnum[k++] : '0';
- }
- }
-
- if(argverbose && !argwindow)
- {
- FPrintf(outfh, " to iff-file '%s' ... ", (ULONG) fname);
- Flush(outfh);
- }
-
- /* Open the file, write a FORM ILBM, and close it again */
-
- if(newpage)
- {
- ifferr = 0;
- ifffptr = fopen(fname, "wb");
- if (ifffptr == NULL) ifferr = 1;
-
- addr1 = ifftell();
- iffputs("FORM"); /* FORM ILBM */
- iffputl(0);
- iffputs("ILBM");
-
- iffputs("BMHD"); /* BMHD */
- iffputl(20);
- iffputw(parm.page.xsize); /* Width */
- iffputw(parm.page.yheight); /* Height */
- iffputw(0); /* X position */
- iffputw(0); /* Y position */
- iffputb(parm.page.depth); /* Number of bit planes */
- iffputb(0); /* Masking: None */
- iffputb(1); /* Compression: ByteRun */
- iffputb(0); /* Pad1 */
- iffputw(0); /* Transparent colour */
- iffputb(xa); /* X aspect */
- iffputb(ya); /* Y aspect */
- iffputw(parm.page.xsize); /* Source width */
- iffputw(parm.page.yheight); /* Source height */
-
- addr2 = ifftell();
- iffputs("CMAP"); /* CMAP */
- iffputl(0);
- for (i = 0; i < colormap.Count; i++)
- {
- w = ((UWORD *) colormap.ColorTable)[i];
- iffputb(((w >> 8) & 15) << 4);
- iffputb(((w >> 4) & 15) << 4);
- iffputb(( w & 15) << 4);
- }
- ifffixup(addr2);
-
- iffputs("CAMG"); /* CAMG */
- iffputl(4);
- iffputl(Options.Screen.ScrDisplayID);
-
- addr2 = ifftell();
- iffputs("BODY"); /* BODY */
- iffputl(0);
-
- counter = 0;
- }
-
- end = my_iff_bm->Rows;
- counter += my_iff_bm->Rows;
- if(counter < parm.page.yheight)
- {
- newpage = FALSE;
- }
- else
- {
- newpage = TRUE;
- end -= counter-parm.page.yheight;
- }
-
- for (j = 0; j < end; j++)
- for (i = 0; i < my_iff_bm->Depth; i++)
- iffpack((char *) my_iff_bm->Planes[i] + j * my_iff_bm->BytesPerRow,
- my_iff_bm->BytesPerRow);
-
- fflush(ifffptr);
- if(newpage)
- {
- ifffixup(addr2);
- ifffixup(addr1);
- if (fclose(ifffptr) == EOF) ifferr = 1;
- }
- if (ifferr) ioerror = errioerror;
- }
-